package com.vast.system.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.StorageClass;
import com.vast.system.exception.BusinessException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Date;

@Component
public class OssUtils {

    @Value("${oss.endpoint}")
    private String endpoint = "https://oss-cn-chengdu.aliyuncs.com";

    @Value("${oss.accessKeyId}")
    private String accessKeyId = "LTAI4Fk9ACgNj18J5feGhQVy";

    @Value("${oss.accessKeySecret}")
    private String accessKeySecret = "epM1H5qhrVnvx7twbCkcp5GFCZ5QEb";

    @Value("${oss.bucketName}")
    private String bucketName = "zfw-bucket";

    private volatile String multipartFileName = null;

    private synchronized String getMultipartFileName() {
        if (multipartFileName == null) {
            multipartFileName = System.currentTimeMillis() + "";
        } else {
            String name = System.currentTimeMillis() + "";
            if (name.equals(multipartFileName)) {
                multipartFileName = name + "1";
            } else {
                multipartFileName = name;
            }
        }
        return multipartFileName;
    }

    /**
     * 上传文件到OSS
     * @param objectName oss路径
     * @param filePath
     */
    public void uploadFile(String objectName, String filePath) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));

        // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
//        ObjectMetadata metadata = new ObjectMetadata();
//        metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
//        metadata.setObjectAcl(CannedAccessControlList.PublicRead);
//        metadata.setContentType();
//        putObjectRequest.setMetadata(metadata);

        // 上传文件。
        ossClient.putObject(putObjectRequest);

        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 上传文件到OSS
     * @param multipartFile
     */
    public String uploadFile(MultipartFile multipartFile) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String originalFilename = multipartFile.getOriginalFilename();
        originalFilename = "multipartFile/" + getMultipartFileName() + originalFilename.substring(originalFilename.lastIndexOf("."));
        try {
            ossClient.putObject(bucketName, originalFilename, multipartFile.getInputStream());
            return getPulicFileUrl(originalFilename);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
        throw new BusinessException("文件上传失败");
    }

    /**
     * 获取私有文件url
     * @param objectName
     * @return
     */
    public String getPrivateFileUrl(String objectName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        // 关闭OSSClient。
        ossClient.shutdown();
        return url.getPath();
    }

    /**
     * 获取公共文件URL
     * @param objectName
     * @return
     */
    public String getPulicFileUrl(String objectName) {
        return endpoint.replace("https://", "https://" + bucketName + ".") + "/" + objectName;
    }

    public void uploadPublicImg(String objectName, File file) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);
        // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        metadata.setObjectAcl(CannedAccessControlList.PublicRead);
        metadata.setContentType(getContentType(file.getName()));
        putObjectRequest.setMetadata(metadata);
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    public void uploadPrivateImg(String objectName, File file) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);
        // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        metadata.setObjectAcl(CannedAccessControlList.Private);
        metadata.setContentType(getContentType(file.getName()));
        putObjectRequest.setMetadata(metadata);
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * @param fileName
     * @return
     */
    private String getContentType(String fileName) {
        if (fileName.endsWith(".bmp")) {
            return "image/bmp";
        }
        if (fileName.endsWith(".gif")) {
            return "image/gif";
        }
        if (fileName.endsWith(".jpeg") || fileName.endsWith(".jpg") || fileName.endsWith(".png")) {
            return "image/jpg";
        }
        return "image/jpg";
    }

}
